fix(library): read footprint and lib-table fields from the parsed tree - #322
fix(library): read footprint and lib-table fields from the parsed tree#322pauliuszaleckas wants to merge 1 commit into
Conversation
|
Holding merge on the two Windows-only CI failures: |
get_footprint_info parsed the footprint for pads, courtyard and model, then still scraped the name and description out of the raw source. parse_lib_table scraped all four of its fields the same way. The scan looked for the literal `(key "` and read to the next quote, so an escaped quote truncated the value — a descr of `0.1" pitch` came back as `0.1\` — and a field written across a line break was missed entirely, leaving the entry blank. Lib-table entries are still located textually before being parsed. The function is infallible by design, and a whole-file parse would let one malformed entry discard every library in the table. The lib-table test helper escapes the values it interpolates, the way KiCad and quote_lib_table_string write them. It interpolated a tempdir path raw, so on Windows the nested table's `\template-fp-lib-table` decoded with a TAB and the entry pointed at a file that does not exist — the two Windows-only failures on this branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0120b5b to
85f3edb
Compare
|
Both Windows failures were the test fixture, not the fix.
The helper now escapes what it interpolates via Verified rather than assumed: pointing Full gate green: 602 lib/tests, doctests, clippy |
Summary
get_footprint_infoandparse_lib_tableread their string fields by scanningthe raw file text instead of the S-expression they had already parsed. Two
user-visible consequences:
0.1" pitch headersas(descr "0.1\" pitch headers"); the scan stopped atthe escaped quote and returned
0.1\.back blank — an fp-lib-table entry loses its nickname, URI and type, so its
libraries stop resolving.
Not linked to an issue. #84 tracks the same root cause elsewhere but explicitly
excludes
parse_lib_table, whose indentation scan was already fixed; this isthe field scraping that remained inside each located block.
Approach
extract_sexp_stringlooked for the literal(key "and read to the next":It has no notion of escapes, of nesting, or of any whitespace other than one
space. Both call sites now read from the parsed tree —
find_str(tag)for atagged field, and the root node's datum for a footprint's name — so escape
decoding and whitespace tolerance come from the parser. The function had no
callers left and is deleted.
Two
get_footprint_infohunks are behaviour-preserving and included only forconsistency:
find_all("pad").len()becomes an explicit direct-child filter(
find_allis already direct-children-only), and!find_all("model").is_empty()becomes
find("model").is_some(), which short-circuits and allocates nothing.Why lib-table entries are still located textually. The obvious move is
parse_sexpover the whole file.parse_lib_tableis infallible by design —every caller path (
read_flat_lib_table→flatten_lib_table) degrades to anempty list and a
tracing::warn!rather than surfacing an error — so awhole-file parse would let one malformed entry silently discard every library
in the table, which for this path means footprint and symbol resolution failing
wholesale. Keeping
find_block_starts+find_balanced_block(both alreadystring-aware and indentation-agnostic) preserves per-entry tolerance while still
removing the scraping. A malformed entry is now skipped with a warning naming
its offset.
Compatibility and safety
No public compatibility impact. No tool, argument, schema, config key or path
changes. Read paths only — nothing here writes a file or touches IPC.
get_footprint_info'snameanddescriptionresponse fields can now return acorrect value where they previously returned a truncated or empty one; no key
is added, removed or renamed.
Validation
All four clean, run against this branch on top of
main(not merely on thedevelopment branch this was cherry-picked from).
The two bug-fix tests were verified to fail against the old scraper before the
fix was restored:
parse_lib_table_skips_only_the_entry_that_does_not_parsepasses both beforeand after — it is not a regression test for a fixed bug, but a guard on the
tolerance property against the whole-file-parse refactor described above. Its
comment says so.
Not run: viewer, plugin, packaging and real-KiCad checks. This touches one file
in
konnect-coreand none of those paths.cargo fmt --all -- --checkcargo test --workspace --locked --lib --tests(what CI runs)cargo test --workspace --locked --doccargo clippy --workspace --locked -- -D warningsReview checklist
docs/NAMING_CONVENTIONS.md; public renames include compatibility handling.